<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>名称解析规则</title>
<link media="all" rel="stylesheet" type="text/css" href="styles/03e73060321a0a848018724a6c83de7f-theme-base.css" />
<link media="all" rel="stylesheet" type="text/css" href="styles/03e73060321a0a848018724a6c83de7f-theme-medium.css" />

 </head>
 <body class="docs"><div class="navbar navbar-fixed-top">
  <div class="navbar-inner clearfix">
    <ul class="nav" style="width: 100%">
      <li style="float: left;"><a href="language.namespaces.fallback.html">« 使用命名空间：后备全局函数/常量</a></li>
      <li style="float: right;"><a href="language.namespaces.faq.html">FAQ：命名空间必知必会 »</a></li>
    </ul>
  </div>
</div>
<div id="breadcrumbs" class="clearfix">
  <ul class="breadcrumbs-container">
    <li><a href="index.html">PHP Manual</a></li>
    <li><a href="language.namespaces.html">命名空间</a></li>
    <li>名称解析规则</li>
  </ul>
</div>
<div id="layout">
  <div id="layout-content"><div id="language.namespaces.rules" class="sect1">
  <h2 class="title">名称解析规则</h2>
  <p class="verinfo">(PHP 5 &gt;= 5.3.0, PHP 7, PHP 8)</p>
  <p class="para">
   在说明名称解析规则之前，我们先看一些重要的定义：
   <dl>
    <strong class="title">命名空间名称定义</strong>
    
     <dt>
非限定名称（Unqualified name）</dt>

     <dd>

      <p class="para">
       名称中不包含命名空间分隔符的标识符，例如 <code class="literal">Foo</code>
      </p>
     </dd>

    
    
     <dt>
限定名称（Qualified name）</dt>

     <dd>

      <p class="para">
       名称中含有命名空间分隔符的标识符，例如 <code class="literal">Foo\Bar</code>
      </p>
     </dd>

    
    
     <dt>
完全限定名称（Fully qualified name）</dt>

     <dd>

      <p class="para">
       名称中包含命名空间分隔符，并以命名空间分隔符开始的标识符，例如 <code class="literal">\Foo\Bar</code>。
       <code class="literal">namespace\Foo</code> 也是一个完全限定名称。
      </p>
     </dd>

    
    
     <dt>
相对名称（Relative name）</dt>

     <dd>

      <p class="para">
       这是个以 <code class="literal">namespace</code> 开头的标识符，
       例如
       <code class="literal">namespace\Foo\Bar</code>。
      </p>
     </dd>

    
   </dl>

  </p>
  <p class="para">
   名称解析遵循下列规则：
   <ol type="1">
    <li class="listitem">
     <span class="simpara">
       完全限定名称总是会解析成没有前缀符号的命名空间名称。
       <code class="literal">\A\B</code> 解析为 <code class="literal">A\B</code>。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      解析相对名称时，会用当前命名空间的名称替换掉 <code class="literal">namespace</code>。
      如果名称出现在全局命名空间，会截掉 <code class="literal">namespace\</code> 前缀。
      例如，在命名空间 <code class="literal">X\Y</code> 里的 <code class="literal">namespace\A</code> 会被解析成 <code class="literal">X\Y\A</code>。
      在全局命名空间里，同样的名字却被解析成 <code class="literal">A</code>。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      对于限定名称，名字的第一段会根据当前 class/namespace 导入表进行翻译。
      比如命名空间 <code class="literal">A\B\C</code> 被导入为 <code class="literal">C</code>，
      名称 <code class="literal">C\D\E</code> 会被翻译成
      <code class="literal">A\B\C\D\E</code>。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      对于限定名称，如果没有应用导入规则，就将当前命名空间添加为名称的前缀。
      例如，位于命名空间 <code class="literal">A\B</code> 内的名称 <code class="literal">C\D\E</code>
      会解析成 <code class="literal">A\B\C\D\E</code>。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      根据符号类型和对应的当前导入表，解析非限定名称。
      这也就是说，根据 class/namespace 导入表翻译类名称；
      根据函数导入表翻译函数名称；
      根据常量导入表翻译常量名称。
      比如，在
      <code class="literal">use A\B\C;</code> 后，类似 <code class="literal">new C()</code> 这样的名称会解析为
      <code class="literal">A\B\C()</code>。
      类似的，<code class="literal">use function A\B\fn;</code> 后，
      <code class="literal">fn()</code> 的用法，解析名称为 <code class="literal">A\B\fn</code>。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      如果没有应用导入规则，对于类似 class 符号的非限定名称，会添加当前命名空间作为前缀。
      比如命名空间 <code class="literal">A\B</code> 内的 <code class="literal">new C()</code> 
      会把名称解析为 <code class="literal">A\B\C</code>。
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      如果没有应用导入规则，非限定名称指向函数或常量，且代码位于全局命名空间之外，则会在运行时解析名称。
      假设代码位于命名空间 <code class="literal">A\B</code> 中，
      下面演示了调用函数
      <code class="literal">foo()</code> 是如何解析的：
     </span>
     <ol type="1">
      <li class="listitem">
       <span class="simpara">
        在当前命名空间中查找函数：
        <code class="literal">A\B\foo()</code>。
       </span>
      </li>
      <li class="listitem">
       <span class="simpara">
        它会尝试找到并调用 <em class="emphasis">全局</em> 的函数
        <code class="literal">foo()</code>。
       </span>
      </li>
     </ol>
    </li>
   </ol>
  </p>
  <div class="example" id="example-316">
   <p><strong>示例 #1 名称解析示例</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">namespace&nbsp;</span><span style="color: #0000BB">A</span><span style="color: #007700">;<br />use&nbsp;</span><span style="color: #0000BB">B</span><span style="color: #007700">\</span><span style="color: #0000BB">D</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">C</span><span style="color: #007700">\</span><span style="color: #0000BB">E&nbsp;</span><span style="color: #007700">as&nbsp;</span><span style="color: #0000BB">F</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">//&nbsp;函数调用<br /><br /></span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;首先尝试调用定义在命名空间"A"中的函数foo()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;再尝试调用全局函数&nbsp;"foo"<br /><br /></span><span style="color: #007700">\</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;调用全局空间函数&nbsp;"foo"&nbsp;<br /><br /></span><span style="color: #0000BB">my</span><span style="color: #007700">\</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;调用定义在命名空间"A\my"中函数&nbsp;"foo"&nbsp;<br /><br /></span><span style="color: #0000BB">F</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;首先尝试调用定义在命名空间"A"中的函数&nbsp;"F"&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;再尝试调用全局函数&nbsp;"F"<br /><br />//&nbsp;类引用<br /><br /></span><span style="color: #007700">new&nbsp;</span><span style="color: #0000BB">B</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;创建命名空间&nbsp;"A"&nbsp;中定义的类&nbsp;"B"&nbsp;的一个对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果未找到，则尝试自动装载类&nbsp;"A\B"<br /><br /></span><span style="color: #007700">new&nbsp;</span><span style="color: #0000BB">D</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;使用导入规则，创建命名空间&nbsp;"B"&nbsp;中定义的类&nbsp;"D"&nbsp;的一个对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果未找到，则尝试自动装载类&nbsp;"B\D"<br /><br /></span><span style="color: #007700">new&nbsp;</span><span style="color: #0000BB">F</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;使用导入规则，创建命名空间&nbsp;"C"&nbsp;中定义的类&nbsp;"E"&nbsp;的一个对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果未找到，则尝试自动装载类&nbsp;"C\E"<br /><br /></span><span style="color: #007700">new&nbsp;\</span><span style="color: #0000BB">B</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;创建定义在全局空间中的类&nbsp;"B"&nbsp;的一个对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果未发现，则尝试自动装载类&nbsp;"B"<br /><br /></span><span style="color: #007700">new&nbsp;\</span><span style="color: #0000BB">D</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;创建定义在全局空间中的类&nbsp;"D"&nbsp;的一个对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果未发现，则尝试自动装载类&nbsp;"D"<br /><br /></span><span style="color: #007700">new&nbsp;\</span><span style="color: #0000BB">F</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;创建定义在全局空间中的类&nbsp;"F"&nbsp;的一个对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果未发现，则尝试自动装载类&nbsp;"F"<br /><br />//&nbsp;调用另一个命名空间中的静态方法或命名空间函数<br /><br /></span><span style="color: #0000BB">B</span><span style="color: #007700">\</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;调用命名空间&nbsp;"A\B"&nbsp;中函数&nbsp;"foo"<br /><br /></span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;调用命名空间&nbsp;"A"&nbsp;中定义的类&nbsp;"B"&nbsp;的&nbsp;"foo"&nbsp;方法<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果未找到类&nbsp;"A\B"&nbsp;，则尝试自动装载类&nbsp;"A\B"<br /><br /></span><span style="color: #0000BB">D</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;使用导入规则，调用命名空间&nbsp;"B"&nbsp;中定义的类&nbsp;"D"&nbsp;的&nbsp;"foo"&nbsp;方法<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果类&nbsp;"B\D"&nbsp;未找到，则尝试自动装载类&nbsp;"B\D"<br /><br /></span><span style="color: #007700">\</span><span style="color: #0000BB">B</span><span style="color: #007700">\</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;调用命名空间&nbsp;"B"&nbsp;中的函数&nbsp;"foo"&nbsp;<br /><br /></span><span style="color: #007700">\</span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;调用全局空间中的类&nbsp;"B"&nbsp;的&nbsp;"foo"&nbsp;方法<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果类&nbsp;"B"&nbsp;未找到，则尝试自动装载类&nbsp;"B"<br /><br />//&nbsp;当前命名空间中的静态方法或函数<br /><br /></span><span style="color: #0000BB">A</span><span style="color: #007700">\</span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;调用命名空间&nbsp;"A\A"&nbsp;中定义的类&nbsp;"B"&nbsp;的&nbsp;"foo"&nbsp;方法<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果类&nbsp;"A\A\B"&nbsp;未找到，则尝试自动装载类&nbsp;"A\A\B"<br /><br /></span><span style="color: #007700">\</span><span style="color: #0000BB">A</span><span style="color: #007700">\</span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;调用命名空间&nbsp;"A\B"&nbsp;中定义的类&nbsp;"B"&nbsp;的&nbsp;"foo"&nbsp;方法<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;如果类&nbsp;"A\B"&nbsp;未找到，则尝试自动装载类&nbsp;"A\B"<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</code></div>
   </div>

  </div>
 </div></div></div></body></html>